package com.lixw.jdbc.util;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: EntityHelper
 * @Description:
 * @Author: xuweiLi
 * @Create: 2025/5/30 18:56
 **/
public class EntityMapperUtils {
    /**
     * 映射字段
     */
    public static <T> T mapToField(T obj, ResultSet resultSet, int index) {
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            String label = metaData.getColumnLabel(index);
            Object object = resultSet.getObject(index);
            Field targetField = TableReflectUtils.findByColumn(label,obj.getClass());
            targetField.setAccessible(true);
            targetField.set(obj,object);
            return obj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 映射实体
     */
    public static <T> T mapToEntity(Class<T> targetClass, ResultSet resultSet) {
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            T obj = targetClass.getConstructor().newInstance();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                //映射字段
                mapToField(obj, resultSet, i);
            }
            return obj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 映射实体列表
     */
    public static <T> List<T> mapToEntityList(Class<T> targetClass, ResultSet resultSet) {
        List<T> entityList = new ArrayList<>();
        try {
            while(resultSet.next()){
                T entity = mapToEntity(targetClass, resultSet);
                entityList.add(entity);
            }
            return entityList;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void setParameters(PreparedStatement ps, Object... params) {
        try {
            for (int i = 0; i < params.length; i++) {
                Object param = params[i];
                if (param == null) {
                    ps.setNull(i + 1, Types.NULL);
                } else {
                    ps.setObject(i + 1, param);
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static void setInsertParameters(PreparedStatement ps,List<String> fieldNames,Object obj) {
        try {
            for (int i = 0; i < fieldNames.size(); i++) {
                Field field = TableReflectUtils.findByColumn(fieldNames.get(i), obj.getClass());
                field.setAccessible(true);
                Object value = field.get(obj);
                if (value == null) {
                    ps.setNull(i + 1, Types.NULL);
                    continue;
                }
                ps.setObject(i + 1, value);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> void setUpdateParameters(PreparedStatement ps, List<String> tableFieldNames, T obj, Object[] args) {
        try {
            int size = tableFieldNames.size();
            for (int i = 0; i < size; i++) {
                Field field = TableReflectUtils.findByColumn(tableFieldNames.get(i), obj.getClass());
                field.setAccessible(true);
                Object value = field.get(obj);
                if (value == null) {
                    ps.setNull(i + 1, Types.NULL);
                    continue;
                }
                ps.setObject(i + 1, value);
            }
            if(args!=null){
                for (int i = 0; i < args.length; i++) {
                    ps.setObject(size+i+1,args[i]);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}